package de.hijacksoft.isle;

import static de.hijacksoft.isle.classes.Variables.*;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RatingBar;
import de.hijacksoft.isle.adapters.DBAdapter;
import de.hijacksoft.isle.classes.Item;
import de.hijacksoft.isle.classes.Recipe;
import de.hijacksoft.isle.adapters.RecipeListAdapter;
import java.util.Collections;
import net.londatiga.android.ActionItem;
import net.londatiga.android.QuickAction;

public class RecipeSelectActivity extends Activity {

    // Constants
    private static final String TAG = "RecipeSelectActivity";
    private ArrayList<Recipe> recipes;
    private RecipeListAdapter myAdapter;
    private DBAdapter adapter;
    // Views
    private Button add, clear, history, sort;
    private ListView list;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.itemselect);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        
        initDB();
        createUI();
        initList();
        Recipe.setSortMode(Recipe.SORT_ALPHA);
        updateSortButton();

    }

    private void initDB() {
        adapter = new DBAdapter(this);
        adapter.open();
    }

    private void createUI() {

        add = (Button) findViewById(R.id.itemselect_btn_add);
        clear = (Button) findViewById(R.id.itemselect_btn_clear);
        history = (Button) findViewById(R.id.itemselect_btn_history);
        list = (ListView) findViewById(R.id.itemselect_list_selectitem);
        sort = (Button) findViewById(R.id.itemselect_btn_sort);

        sort.setVisibility(View.VISIBLE);
        
        //remove unused buttons
        history.setVisibility(View.GONE);
        clear.setVisibility(View.GONE);

        add.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                startActivityForResult(new Intent(RecipeSelectActivity.this, RecipeActivity.class), RECIPE_RETURNED);
            }
        });

        // Build Sort QuickAction
        final QuickAction qa = new QuickAction(this);

        ActionItem qa_alphabet = new ActionItem();
        qa_alphabet.setTitle(getString(R.string.sort_alphabet));
        qa_alphabet.setIcon(getResources().getDrawable(R.drawable.qa_alphabet));
        qa.addActionItem(qa_alphabet);

        ActionItem qa_period = new ActionItem();
        qa_period.setTitle(getString(R.string.rating));
        qa_period.setIcon(getResources().getDrawable(R.drawable.rating));
        qa.addActionItem(qa_period);

        qa.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {

            @Override
            public void onItemClick(int pos) {
                switch (pos) {
                    case 0:
                        Recipe.setSortMode(Recipe.SORT_ALPHA);
                        break;
                    case 1:
                        Recipe.setSortMode(Recipe.SORT_RATING);
                        break;
                }
                updateSortButton();
                Collections.sort(recipes);
                myAdapter.notifyDataSetChanged();
            }
        });

        sort.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Collections.sort(recipes);
                myAdapter.notifyDataSetChanged();
                qa.show(sort);
            }
        });

        clear.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                clearListQuestion();
            }
        });

        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                //insert recipe ingredients into main list
                InsertRecipeTask rt = new InsertRecipeTask();
                rt.execute(arg2);

            }
        });

        list.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                ItemEditQuestion(arg2);
                return false;

            }
        });
    }

    /**
     * Asks the user to whether to edit or to remove a recipe from the database
     * @param position the position in the ArrayList
     */
    private void ItemEditQuestion(final int position) {
        AlertDialog.Builder dB = new AlertDialog.Builder(this);
        LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(R.layout.rating_dialog, null);
        RatingBar rbar = (RatingBar) layout.findViewById(R.id.rating_dialog_ratingbar);
        rbar.setRating((float) recipes.get(position).rating);
        dB.setView(layout);
        dB.setTitle(recipes.get(position).name);
        dB.setPositiveButton(getString(R.string.edit), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                Intent intent = new Intent(RecipeSelectActivity.this, RecipeActivity.class);
                intent.putExtra(KEY_ID, recipes.get(position).id);
                startActivityForResult(intent, RECIPE_RETURNED);
            }
        });
        dB.setNegativeButton(getString(R.string.delete), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                adapter.removeFromRecipeList(recipes.get(position).id);
                recipes.remove(position);
                myAdapter.notifyDataSetChanged();
            }
        });
        AlertDialog d = dB.create();
        d.show();
    }

    /**
     * changes the name and Icons of the SortButton
     */
    private void updateSortButton() {
        if (myAdapter.getCount() > 0) {
            sort.setEnabled(true);
            switch (Recipe.getSortMode()) {
                case Recipe.SORT_ALPHA:
                    sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_alphabet, 0, 0);
                    sort.setText(R.string.sort_alphabet);
                    break;
                case Recipe.SORT_RATING:
                    sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_rating, 0, 0);
                    sort.setText(R.string.rating);
                    break;
            }
        } else {
            sort.setEnabled(false);
            sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_alphabet, 0, 0);
            sort.setText(R.string.sort_alphabet);
        }
    }

    private void checkClearButton() {
        if (myAdapter.getCount() > 0) {
            clear.setEnabled(true);
        } else {
            clear.setEnabled(false);
        }
    }

    private void initList() {
        
        recipes = new ArrayList<Recipe>();

        myAdapter = new RecipeListAdapter(RecipeSelectActivity.this, R.layout.recipe, recipes) {

            @Override
            public void onDataSetChange() {
                updateSortButton();
            }
        };

        list.setAdapter(myAdapter);
        
        new Thread(){
            
            @Override
            public void run(){
                
                try{
                    
                    ArrayList<Integer> recipeIDs = adapter.getRecipeIDs();
                    
                    for(Integer id : recipeIDs) {
                        
                        if(!adapter.isOpen()) break;
                        
                        recipes.add(adapter.getRecipeById(id));

                        Collections.sort(recipes);

                        new Handler(Looper.getMainLooper()).post(new Thread(){

                            @Override
                            public void run(){
                                myAdapter.notifyDataSetChanged();
                            }

                        });

                    }
                    
                }
                catch(IllegalStateException ex){
                    Log.i(TAG, "Error during initList Thread: " + ex.getMessage());
                }
                catch(android.database.StaleDataException ex){
                    Log.i(TAG, "Error during initList Thread: " + ex.getMessage());
                }

            }
            
        }.start();        
        
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case RECIPE_RETURNED:
                    initList();
                    break;
            }
        }

        updateSortButton();
        myAdapter.notifyDataSetChanged();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        startActivity(new Intent(this, Preferences.class));
        return false;
    }

    public void clearListQuestion() {
        AlertDialog.Builder dB = new AlertDialog.Builder(this);
        dB.setTitle(getString(R.string.clear));
        dB.setMessage(getString(R.string.clearlist));
        dB.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                adapter.clearRecipeList();
                recipes.clear();
                myAdapter.notifyDataSetChanged();
            }
        });
        dB.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                //do nothing
            }
        });
        AlertDialog d = dB.create();
        d.show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        checkClearButton();
    }

    /**
     * inserts all items of one recipe into the mainList of the database
     * @author HiJack Soft
     */
    private class InsertRecipeTask extends AsyncTask<Integer, Integer, Integer> {

        private ProgressDialog pd;

        @Override
        protected void onPreExecute() {
            pd = ProgressDialog.show(RecipeSelectActivity.this, getString(R.string.app_name), getString(R.string.busy), true, false);
        }

        @Override
        protected Integer doInBackground(Integer... arg) {
            Recipe recipe = recipes.get(arg[0]);

            recipe.lastBought = System.currentTimeMillis();
            adapter.updateRecipe(recipe);

            for (int i = 0; i < recipes.get(arg[0]).ingredients.size(); i++) {
                Item ingredient = recipe.ingredients.get(i);
                ingredient.category.name = recipe.name;
                ingredient.category.id = adapter.getCategoryIdByName(recipe.name);
                adapter.addToMainList(ingredient);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Integer result) {
            pd.dismiss();
            RecipeSelectActivity.this.setResult(RESULT_OK, null);
            RecipeSelectActivity.this.finish();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        try{
            adapter.close();
        }
        catch(android.database.SQLException ex){
            Log.i(TAG, "Unable to close Database adapter: " + ex.getMessage());
        }
    }
}
